package com.ntd.study.algorithm.reduce.rtf;

import com.ntd.study.algorithm.reduce.StudyReduceMes;

import java.util.*;

public class Compression {
    public static void main(String[] argc) {
        lengthCoding(StudyReduceMes.mes);
    }

    private static void lengthCoding(String src) {
        String result = runLengthCoding(src);
        System.out.println("原字符串：" + src);
        System.out.println("原字符串长度：" + src.length());
        System.out.println("压缩字符：" + result);
        System.out.println("压缩字符长度：" + result.length());
        System.out.println("解压字符：" + runLengthCoding_read(result));
    }

    //行程编码加密
    private static String runLengthCoding(String src) {
        src = src + "#";//最后填一个#用于方便最后一个before可以输出
        List<String> result = new ArrayList<String>();//存放结果
        List<Character> temp = new ArrayList<Character>();//存放临时变量和数数
        char before = src.charAt(0);//前后字符参照对比
        for (int i = 1; i < src.length(); i++) {
            if (src.charAt(i) == before)//相同都暂时存放在temp里
            {
                temp.add(before);
            } else {
                if (temp.size() >= 3)//加上before一共4位
                {
                    result.add(temp.get(0) + "#" + (temp.size() + 1) + "#");//before没有加进去所以大小要加1
                } else {
                    if (temp.isEmpty()) {
                        result.add(String.valueOf(before));
                    } else {
                        StringBuilder temp2 = new StringBuilder();
                        temp2.append(temp.get(0));
                        for (int j = 1; j < temp.size(); j++) {
                            temp2.append(temp.get(j));
                        }
                        temp2.append(before);
                        result.add(temp2.toString());
                    }
                }
                temp = new ArrayList<Character>();
            }
            before = src.charAt(i);
        }

        //生成字符串
        StringBuilder answer = new StringBuilder(result.get(0));
        for (int i = 1; i < result.size(); i++) {
            answer.append(result.get(i));
        }
        return answer.toString();
    }

    //行程编码解密
    private static String runLengthCoding_read(String src) {
        char before = src.charAt(0);
        StringBuilder result = new StringBuilder();
        for (int i = 1; i < src.length(); i++) {
            if (src.charAt(i) == '#') {
                StringBuilder temp = new StringBuilder();
                i++;
                while (src.charAt(i) != '#') {
                    temp.append(src.charAt(i));
                    i++;
                }
                int length = Integer.parseInt(temp.toString());
                for (int j = 0; j < length; j++) {
                    result.append(before);
                }
                if (i < src.length() - 1)//特殊情况特殊处理。此处应该可以优化掉。但是没空了。。
                {
                    before = src.charAt(++i);
                    if (i == src.length() - 1)
                        result.append(before);
                }
            } else {
                result.append(before);
                before = src.charAt(i);
                if (i == src.length() - 1)//特殊情况特殊处理。此处应该可以优化掉。但是没空了。。
                    result.append(before);
            }
        }
        return result.toString();
    }
}